<template>
  <el-container>
    <el-header class="x-header">
      <el-row type="flex" justify="center" align="center">
        <!-- logo -->
        <el-col :md="6" :sm="8">
          <div class="wrap-logo">
            <a href="/home" class="logo">
              <img class="logo-img" src="../assets/logo.png" alt />
              <h2 class="logo-title x-link-ink hidden-xs-only">信博园</h2>
            </a>
          </div>
        </el-col>
        <!-- 搜索栏 -->
        <el-col :md="8" :sm="8">
          <div class="search">
            <input
              type="text"
              class="layui-input"
              v-model="keyword"
              :placeholder="placeholder"
              @focus="placeholder = ''"
              @blur="placeholder = '请输入关键字'"
              @keydown.enter="search"
            />
            <button class="x-btn" @click="search">
              <i class="layui-icon layui-icon-search"></i>
            </button>
          </div>
        </el-col>
        <!-- 登陆、注册 -->
        <el-col :md="6" :sm="8" style="justify-content: flex-end">
          <div
            v-if="logged"
            class="wrap-avatar"
            @mouseenter="show = true"
            @mouseleave="show = false"
          >
            <a href="/profile">
              <img class="avatar" :src="avatar" alt="头像" />
            </a>
            <el-collapse-transition>
              <ul class="bubble" v-show="show" @click="show = false">
                <li>
                  <a href="/profile">个人中心</a>
                </li>
                <li>
                  <a href="/profile/editor">撰写文章</a>
                </li>
                <li>
                  <a @click="exit">退出</a>
                </li>
              </ul>
            </el-collapse-transition>
          </div>
          <div v-else class="x-btn-container">
            <button
              class="x-btn x-btn-primary"
              @click="loginDialogVisible = true"
            >
              登 录
            </button>
            <button class="x-btn" @click="registerDialogVisible = true">
              注 册
            </button>
          </div>
        </el-col>
      </el-row>
    </el-header>
    <!-- 登录对话框 -->
    <el-dialog
      :visible.sync="loginDialogVisible"
      :destroy-on-close="true"
      title="账号密码登录"
      width="28.5rem"
      center
      @close="resetForm('logForm')"
    >
      <el-form
        :model="logForm"
        :status-icon="true"
        :rules="logRules"
        ref="logForm"
      >
        <el-form-item prop="account">
          <el-input
            type="text"
            v-model="logForm.account"
            autocomplete="on"
            placeholder="请输入账号"
          >
            <i slot="prefix" class="el-icon-user"></i>
          </el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input
            type="password"
            v-model="logForm.password"
            autocomplete="off"
            placeholder="请输入密码"
            show-password
            @keyup.enter.native="submitLogForm('logForm')"
          >
            <i slot="prefix" class="el-icon-lock"></i>
          </el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <button
          type="button"
          @click="submitLogForm('logForm')"
          class="fluid-button x-btn"
        >
          <i v-if="loading" class="el-icon-loading"></i>
          登 录
        </button>
        <p class="tip">忘记密码？</p>
      </div>
    </el-dialog>
    <!-- 注册对话框 -->
    <el-dialog
      :visible.sync="registerDialogVisible"
      :destroy-on-close="true"
      title="用户注册"
      width="28.5rem"
      center
      @close="resetForm('regForm')"
    >
      <el-form
        :model="regForm"
        :status-icon="true"
        :rules="regRules"
        ref="regForm"
      >
        <el-form-item prop="username">
          <el-input
            type="text"
            v-model="regForm.username"
            autocomplete="on"
            placeholder="请输入用户名"
          >
            <i slot="prefix" class="el-icon-user"></i>
          </el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input
            type="password"
            v-model="regForm.password"
            autocomplete="off"
            minlength="6"
            placeholder="请输入密码"
            show-password
          >
            <i slot="prefix" class="el-icon-lock"></i>
          </el-input>
        </el-form-item>
        <el-form-item prop="checkPass">
          <el-input
            type="password"
            v-model="regForm.checkPass"
            autocomplete="off"
            minlength="6"
            placeholder="请确认密码"
            show-password
          >
            <i slot="prefix" class="el-icon-lock"></i>
          </el-input>
        </el-form-item>
        <el-form-item prop="email">
          <el-input
            type="email"
            v-model="regForm.email"
            autocomplete="on"
            placeholder="请输入邮箱"
          >
            <i slot="prefix" class="el-icon-message"></i>
          </el-input>
        </el-form-item>
        <el-form-item prop="code" class="verify-code">
          <el-input
            type="text"
            v-model="regForm.code"
            autocomplete="on"
            placeholder="请输入验证码"
            @keyup.enter.native="submitRegForm('regForm')"
          >
            <i slot="prefix" class="el-icon-lock"></i>
          </el-input>
          <button
            :disabled="loadingCode"
            type="button"
            @click="getCode"
            class="x-btn"
            v-bind:class="{ 'x-btn-disabled': loadingCode }"
          >
            <i v-if="loadingCode" class="el-icon-loading"></i>
            获取验证码
          </button>
        </el-form-item>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <button
          type="button"
          :disabled="regBtnDisabled"
          class="fluid-button x-btn"
          @click="submitRegForm('regForm')"
          v-bind:class="{ 'x-btn-disabled': regBtnDisabled }"
        >
          <i v-if="loading" class="el-icon-loading"></i>
          注 册
        </button>
      </div>
    </el-dialog>
  </el-container>
</template>

<script>
import { parseToken, setToken } from "@/utils/auth";
import { login, logout, register } from "@/api/user";
import { Message } from "element-ui";
import request from "@/utils/request";

export default {
  name: "",
  data() {
    const isEmpty = (value) => value == null || value.trim() === "";
    // 校验规则
    // - 非空校验
    const notBlank = (rule, value, callback) => {
      if (isEmpty(value)) {
        callback(new Error("必填项不能为空！"));
      } else {
        callback();
      }
    };
    // - 邮箱校验
    const validateEmail = (rule, value, callback) => {
      if (isEmpty(value)) {
        callback(new Error("请输入邮箱！"));
      } else {
        let reg = new RegExp(/^([\w\d_.-])+@([\w\d_.-])+\.(\w{2,})$/);
        if (!reg.test(value)) {
          callback(new Error("邮箱格式不正确"));
        } else {
          // 发送请求校验邮箱是否重复
          request
            .get("/checkEmail", { params: { email: value } })
            .then((res) => {
              if (res.code !== 200) {
                callback(new Error(res.message));
              } else {
                callback();
              }
            })
            .catch((err) => {
              callback();
            });
        }
      }
    };
    // - 密码校验
    const validatePassword = (rule, value, callback) => {
      if (isEmpty(value)) {
        callback(new Error("请输入密码！"));
      } else {
        if (!isEmpty(this.regForm.checkPass)) {
          this.$refs.regForm.validateField("validatePasswordAgain");
        }
        callback();
      }
    };
    // - 密码二次校验
    const validatePasswordAgain = (rule, value, callback) => {
      if (isEmpty(value)) {
        callback(new Error("请再次输入密码"));
      } else if (value !== this.regForm.password) {
        callback(new Error("两次输入密码不一致!"));
      } else {
        callback();
      }
    };
    // 数据绑定
    return {
      // 关键字搜索
      keyword: "",
      // 占位符内容
      placeholder: "请输入关键字",
      // 验证码按钮加载中
      loadingCode: false,
      // 禁用注册按钮，发送验证码后解禁
      regBtnDisabled: true,
      // 登录按钮加载中
      loading: false,
      // 登录对话框是否可见
      loginDialogVisible: false,
      // 注册对话框是否可见
      registerDialogVisible: false,
      // 登录表单
      logForm: {
        account: "",
        password: "",
      },
      // 注册表单
      regForm: {
        username: "",
        password: "",
        checkPass: "",
        email: "",
        // 验证码
        code: "",
      },
      // 登录表单校验规则
      logRules: {
        // 使用非空校验，失去焦点时触发
        account: [{ validator: notBlank, trigger: "blur" }],
        // 使用密码校验，失去焦点时触发
        password: [
          { validator: validatePassword, trigger: "blur" },
          { min: 6, max: 18, message: "密码长度为6~18" },
        ],
      },
      // 注册表单校验规则
      regRules: {
        // 使用非空校验，失去焦点时触发
        username: [{ validator: notBlank, trigger: "blur" }],
        // 使用邮箱校验，失去焦点时触发
        email: [{ validator: validateEmail, trigger: "blur" }],
        // 使用密码校验，失去焦点时触发
        password: [
          { validator: validatePassword, trigger: "blur" },
          { min: 6, max: 18, message: "密码长度为6~18" },
        ],
        // 使用密码二次校验，失去焦点时触发
        checkPass: [{ validator: validatePasswordAgain, trigger: "blur" }],
        code: [{ validator: notBlank, trigger: "blur" }],
      },
      // 是否显示个人中心列表
      show: false,
    };
  },
  computed: {
    logged() {
      const token = this.$store.getters.token;
      if (token == null) {
        return false;
      } else {
        return true;
      }
    },
    avatar() {
      return this.$store.getters.avatar;
    },
  },
  methods: {
    search() {
      if (this.keyword.trim() !== "") {
        this.$router.push({
          path: "/home",
          query: {
            keyword: this.keyword,
          },
        });
        this.keyword = '';
      }
    },
    /**
     * 提交登录表单
     */
    submitLogForm(formName) {
      // 防止频繁点击
      if (this.loading === true) {
        Message({
          message: "登录中，请耐心等待~",
          duration: 1500,
          center: true,
        });
        return false;
      }
      // 校验表单
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.loading = true;
          login(this.qs.stringify(this.logForm))
            .then((res) => {
              // 登录成功：保存token，关闭对话框
              this.loading = false;
              this.loginDialogVisible = false;
              this.$store.commit("user/SET_TOKEN", res.token);
              setToken(res.token);
              this.resetForm("logForm");
            })
            .catch((err) => {
              this.loading = false;
              console.error(err);
            });
        } else {
          return false;
        }
      });
    },
    /**
     * 提交注册表单
     */
    submitRegForm(formName) {
      // 防止频繁点击
      if (this.loading === true) {
        Message({
          message: "注册中，请耐心等待~",
          duration: 1500,
          center: true,
        });
        return false;
      }
      // 校验表单
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.loading = true;
          register(this.regForm)
            .then((res) => {
              // 注册成功
              this.loading = false;
              this.registerDialogVisible = false;
              this.$store.commit("user/SET_TOKEN", res.token);
              setToken(res.token);
              this.resetForm("regForm");
            })
            .catch((err) => {
              this.loading = false;
              console.log(err);
            });
        } else {
          return false;
        }
      });
    },
    /**
     * 重置指定表单
     */
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    /**
     * 获取验证码
     */
    getCode() {
      // 防止重复点击
      if (this.loadingCode === true) {
        Message({
          message: "验证码已发送，请耐心等待~",
          duration: 1500,
          center: true,
        });
        return false;
      }
      // 检验邮箱格式
      const regex = new RegExp(/^([\w\d_.-])+@([\w\d_.-])+\.(\w{2,})$/);
      const email = this.regForm.email;
      if (!regex.test(email)) {
        Message({
          message: "请输入正确的邮箱！",
          type: "error",
          duration: 1500,
          center: true,
        });
      } else {
        // 发送验证码
        // 验证码按钮进入加载状态
        this.loadingCode = true;
        request
          .get("/authCode", { params: { email: email } })
          .then((res) => {
            // 提示信息
            Message({
              message: res.message,
              duration: 1500,
              center: true,
            });
            // 结束按钮的加载状态
            this.loadingCode = false;
            // 更改注册按钮的状态
            this.regBtnDisabled = res.code !== 200;
          })
          .catch((err) => {
            this.loadingCode = false;
            console.error(err);
          });
      }
    },
    /**
     * 退出登录
     */
    exit() {
      this.$store.dispatch("user/logout").then(() => {
        this.$router.push("/home");
      });
    },
  },
  created() {
    // 是否登录
    // if (this.logged) {
    //   const token = this.$store.getters.token;
    //   this.user = parseToken(token);
    //   console.log(this.user);
    // }
  },
};
</script>

<style scope>
  .x-header {
    width: 100%;
    background-color: #fff;
    height: 50px !important;
    line-height: 50px;
    /*box-shadow: 0 1px 5px #eee;*/
    font-size: 0;
    border-bottom: 1px solid #5fb878;
  }
  .x-header .el-row {
    margin: 0;
  }
  .x-header .el-row .el-col {
    display: flex;
    align-items: center;
  }
  .x-header-fixed {
    position: fixed;
    top: 0;
    z-index: 999;
  }

  .wrap-logo {
    width: fit-content;
    -webkit-user-select: none;
  }
  .logo .logo-img {
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
  }
  .logo .logo-title {
    display: inline;
    font-size: 2rem;
    vertical-align: middle;
    margin-left: 5px;
    font-family: "STXingkai", "Microsoft YaHei", sans-serif;
  }

  .x-link-ink {
    color: #074b60;
    opacity: 0.8;
  }
  .x-link-ink:hover {
    opacity: 1;
  }

  .search {
    position: relative;
    width: 100%;
    height: 2rem;
    border-radius: 2px;
    /*background-color: #ffffff;*/
    /*margin: 10px 0;*/
  }
  .search > input {
    position: absolute;
    top: 0;
    left: 0;
    width: 80%;
    height: inherit;
    font-size: 1rem;
    box-sizing: border-box;
    border-right: 0;
    border-top-right-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
  }
  .search > input:hover {
    border-color: #5fb878;
  }
  .search > input:focus {
    font-weight: 400;
    border-color: #5fb878 !important;
  }
  .search > button {
    position: absolute;
    top: 0;
    right: 0;
    width: 20%;
    height: inherit;
    border: 1px solid #5fb878;
    border-left: 0;
    border-radius: 0 2px 2px 0 !important;
    background-color: #5fb878;
    color: #fff;
    padding: 0;
  }

  .x-btn-container {
    line-height: 0;
  }

  .wrap-avatar {
    position: relative;
  }
  .wrap-avatar .avatar {
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    cursor: pointer;
    -webkit-user-select: none;
  }
  .wrap-avatar .bubble {
    position: absolute;
    top: 100%;
    background-color: #fff;
    transform: translateX(-1.5rem);
    border-radius: 2px;
    box-shadow: 1px 1px 5px 0 #ccc;
    text-align: center;
    z-index: 999;
  }
  .wrap-avatar .bubble > li > a {
    display: block;
    width: 64px;
    padding: 5px 8px;
    font-size: 14px;
    line-height: 2;
    box-sizing: content-box;
    transition: all 0.1s;
  }
  .wrap-avatar .bubble > li > a:hover {
    background-color: #f8f8f8;
    color: #5fb878;
  }

  .el-input {
    margin-bottom: 0 !important;
  }

  .verify-code .el-input {
    width: 60%;
  }
  .verify-code .x-btn {
    margin-left: 1.2rem;
  }
</style>